home *** CD-ROM | disk | FTP | other *** search
/ Aminet 40 / Aminet 40 (2000)(Schatztruhe)[!][Dec 2000].iso / Aminet / dev / lang / Python16_Src.lha / Python16_Source / Tools / idle / ReplaceDialog.py < prev    next >
Encoding:
Python Source  |  1999-06-08  |  5.1 KB  |  173 lines

  1. import string
  2. import os
  3. import re
  4. import fnmatch
  5. from Tkinter import *
  6. import tkMessageBox
  7. import SearchEngine
  8. from SearchDialogBase import SearchDialogBase
  9.  
  10. def replace(text):
  11.     root = text._root()
  12.     engine = SearchEngine.get(root)
  13.     if not hasattr(engine, "_replacedialog"):
  14.         engine._replacedialog = ReplaceDialog(root, engine)
  15.     dialog = engine._replacedialog
  16.     dialog.open(text)
  17.  
  18. class ReplaceDialog(SearchDialogBase):
  19.  
  20.     title = "Replace Dialog"
  21.     icon = "Replace"
  22.  
  23.     def __init__(self, root, engine):
  24.         SearchDialogBase.__init__(self, root, engine)
  25.         self.replvar = StringVar(root)
  26.  
  27.     def open(self, text):
  28.         SearchDialogBase.open(self, text)
  29.         try:
  30.             first = text.index("sel.first")
  31.         except TclError:
  32.             first = None
  33.         try:
  34.             last = text.index("sel.last")
  35.         except TclError:
  36.             last = None
  37.         first = first or text.index("insert")
  38.         last = last or first
  39.         self.show_hit(first, last)
  40.         self.ok = 1
  41.  
  42.     def create_entries(self):
  43.         SearchDialogBase.create_entries(self)
  44.         self.replent = self.make_entry("Replace with:", self.replvar)
  45.  
  46.     def create_command_buttons(self):
  47.         SearchDialogBase.create_command_buttons(self)
  48.         self.make_button("Find", self.find_it)
  49.         self.make_button("Replace", self.replace_it)
  50.         self.make_button("Replace+Find", self.default_command, 1)
  51.         self.make_button("Replace All", self.replace_all)
  52.  
  53.     def find_it(self, event=None):
  54.         self.do_find(0)
  55.  
  56.     def replace_it(self, event=None):
  57.         if self.do_find(self.ok):
  58.             self.do_replace()
  59.  
  60.     def default_command(self, event=None):
  61.         if self.do_find(self.ok):
  62.             self.do_replace()
  63.             self.do_find(0)
  64.  
  65.     def replace_all(self, event=None):
  66.         prog = self.engine.getprog()
  67.         if not prog:
  68.             return
  69.         repl = self.replvar.get()
  70.         text = self.text
  71.         res = self.engine.search_text(text, prog)
  72.         if not res:
  73.             text.bell()
  74.             return
  75.         text.tag_remove("sel", "1.0", "end")
  76.         text.tag_remove("hit", "1.0", "end")
  77.         line = res[0]
  78.         col = res[1].start()
  79.         if self.engine.iswrap():
  80.             line = 1
  81.             col = 0
  82.         ok = 1
  83.         first = last = None
  84.         # XXX ought to replace circular instead of top-to-bottom when wrapping
  85.         text.undo_block_start()
  86.         while 1:
  87.             res = self.engine.search_forward(text, prog, line, col, 0, ok)
  88.             if not res:
  89.                 break
  90.             line, m = res
  91.             chars = text.get("%d.0" % line, "%d.0" % (line+1))
  92.             orig = m.group()
  93.             new = re.pcre_expand(m, repl)
  94.             i, j = m.span()
  95.             first = "%d.%d" % (line, i)
  96.             last = "%d.%d" % (line, j)
  97.             if new == orig:
  98.                 text.mark_set("insert", last)
  99.             else:
  100.                 text.mark_set("insert", first)
  101.                 if first != last:
  102.                     text.delete(first, last)
  103.                 if new:
  104.                     text.insert(first, new)
  105.             col = i + len(new)
  106.             ok = 0
  107.         text.undo_block_stop()
  108.         if first and last:
  109.             self.show_hit(first, last)
  110.         self.close()
  111.  
  112.     def do_find(self, ok=0):
  113.         if not self.engine.getprog():
  114.             return 0
  115.         text = self.text
  116.         res = self.engine.search_text(text, None, ok)
  117.         if not res:
  118.             text.bell()
  119.             return 0
  120.         line, m = res
  121.         i, j = m.span()
  122.         first = "%d.%d" % (line, i)
  123.         last = "%d.%d" % (line, j)
  124.         self.show_hit(first, last)
  125.         self.ok = 1
  126.         return 1
  127.  
  128.     def do_replace(self):
  129.         prog = self.engine.getprog()
  130.         if not prog:
  131.             return 0
  132.         text = self.text
  133.         try:
  134.             first = pos = text.index("sel.first")
  135.             last = text.index("sel.last")
  136.         except TclError:
  137.             pos = None
  138.         if not pos:
  139.             first = last = pos = text.index("insert")
  140.         line, col = SearchEngine.get_line_col(pos)
  141.         chars = text.get("%d.0" % line, "%d.0" % (line+1))
  142.         m = prog.match(chars, col)
  143.         if not prog:
  144.             return 0
  145.         new = re.pcre_expand(m, self.replvar.get())
  146.         text.mark_set("insert", first)
  147.         text.undo_block_start()
  148.         if m.group():
  149.             text.delete(first, last)
  150.         if new:
  151.             text.insert(first, new)
  152.         text.undo_block_stop()
  153.         self.show_hit(first, text.index("insert"))
  154.         self.ok = 0
  155.         return 1
  156.  
  157.     def show_hit(self, first, last):
  158.         text = self.text
  159.         text.mark_set("insert", first)
  160.         text.tag_remove("sel", "1.0", "end")
  161.         text.tag_add("sel", first, last)
  162.         text.tag_remove("hit", "1.0", "end")
  163.         if first == last:
  164.             text.tag_add("hit", first)
  165.         else:
  166.             text.tag_add("hit", first, last)
  167.         text.see("insert")
  168.         text.update_idletasks()
  169.  
  170.     def close(self, event=None):
  171.         SearchDialogBase.close(self, event)
  172.         self.text.tag_remove("hit", "1.0", "end")
  173.